package demo.miner;

import java.awt.Image;

import jtech.Drawer;
import jtech.math.Math2;
import jtech.math.Vec2f;

public abstract class Entity<T extends ClassEntity> {
	
	private int id;
	private Team team;
	
	protected Vec2f position = new Vec2f();
	protected float heading = Math2.randomRadians(); // Radians
	
	private int hitPoints;
	private T classEntity;

	private boolean selectable = true;
	private boolean selected;

	private boolean selectionOver;
	private boolean mouseOver;

	private boolean[] mouseButton = new boolean[3];
	
	public Entity(T classEntity) {
		this.classEntity = classEntity;
		hitPoints = classEntity.getBaseHitPoints();
	}

    public void fireEvents(Game game) {
    	
    	if (game.isDragOver(this) && game.getTeamPlayer() == team && isUnit()) {
    		if (selectionOver == false) {
    			selectionOver = true;
    			onSelectionEnter(game);
    		}
    	} else {
    		if (selectionOver == true && game.getTeamPlayer() == team && isUnit()) {
    			selectionOver = false;
    			onSelectionExit(game);
    		}
    	}
    	
    	if (game.isMouseOver(this)) {
			if (mouseOver == false) {
				mouseOver = true;
				onMouseEnter(game);
			}
		} else {
			if (mouseOver == true) {
				mouseOver = false;
				onMouseExit(game);
			}
		}
		
    	for (int i = 0; i < 3; i++) {
			if (game.isMouseButton()[i] && mouseOver) {
				if (mouseButton[i] == false) {
					mouseButton[i] = true;
				}
			} else {
				if (mouseButton[i] && mouseOver) {
					onClick(game, i);
				}
				mouseButton[i] = false;
			}
    	}
    }

    /** Events */
    public void onClick(Game game, int button) {
    	
    }
    
    public void onMouseEnter(Game game) {
    	
    }
    
    public void onMouseExit(Game game) {
    	
    }
    
    public void onSelectionEnter(Game game) {
    	
    }
    
    public void onSelectionExit(Game game) {
    	
    }
    
    //
	public void update(Game game, float elapsedTime) {

	}

	// draws
	public void drawDebug(Game game, Drawer drawer) {
		
	}
	
	public void drawSelection(Game game, Drawer drawer) {
			
	}
	
	public void drawLifeBar(Game game, Drawer drawer) {
		
	}
	
	public void drawImage(Game game, Drawer drawer) {
		
	}
	
	//
	public boolean isUnit() {
		return this instanceof EntityUnit;
	}
    
    public boolean isBuilding() {
    	return this instanceof EntityBuilding;
    }
    
    public EntityUnit asUnit() {
    	return isUnit() ? (EntityUnit) this : null;
    }
    
    public EntityBuilding asBuilding() {
    	return isBuilding() ? (EntityBuilding) this : null;
    }

    public float getCenterX() {
    	return isBuilding() ? position.x + (getSpriteWidth()*.5f) : position.x;
    }
    
    public float getCenterY() {
    	return isBuilding() ? position.y + (getSpriteHeight()*.5f) : position.y;
    }
    
	public boolean isDead() {
		return hitPoints <= 0;
	}
	
	public void receivesOrder(Order order) {
		
	}
    
	/** Delegate methods from EntityClass*/
	public float getBaseRadius() {
		return classEntity.getBaseRadius();
	}
	
	public float getBaseHitPoints() {
		return classEntity.getBaseHitPoints();
	}
	
	public String getClassName() {
		return classEntity.getEntityClass().getCanonicalName();
	}

	public Image getSpriteImage() {
		return classEntity.getSpriteImage();
	}

	public int getSpriteOffsetX() {
		return classEntity.getSpriteOffsetX();
	}

	public int getSpriteOffsetY() {
		return classEntity.getSpriteOffsetY();
	}

	public int getSpriteWidth() {
		return classEntity.getSpriteWidth();
	}

	public int getSpriteHeight() {
		return classEntity.getSpriteHeight();
	}

	public int getBaseArmor() {
		return classEntity.getBaseArmor();
	}

	public int getBaseDamage() {
		return classEntity.getBaseDamage();
	}

	public int getBaseAttackRange() {
		return classEntity.getBaseAttackRange();
	}

	public float getBaseReloadTime() {
		return classEntity.getBaseReloadTime();
	}

	public int getGoldCost() {
		return classEntity.getGoldCost();
	}
	
	public boolean isCanAttack() {
		return classEntity.isCanAttack();
	}

	/** GETTERS AND SETTERS */
	public void setId(int id) {
		this.id = id;
	}

	public int getId() {
		return id;
	}

	public boolean isSelected() {
		return selected;
	}

	public void setSelected(boolean selected) {
		this.selected = selected;
	}

	public boolean isSelectable() {
		return selectable;
	}

	public void setSelectable(boolean selectable) {
		this.selectable = selectable;
	}

	public float getX() {
		return position.x;
	}

	public void setX(float x) {
		this.position.x = x;
	}

	public float getY() {
		return position.y;
	}

	public void setY(float y) {
		this.position.y = y;
	}

	public Vec2f getPosition() {
		return position;
	}

	public void setPosition(Vec2f position) {
		this.position = position;
	}
	
	public float getHeading() {
		return heading;
	}

	public void setHeading(float heading) {
		this.heading = heading;
	}

	public T getClassEntity() {
		return classEntity;
	}

	public Team getTeam() {
		return team;
	}

	public void setTeam(Team team) {
		this.team = team;
	}

	public boolean isSelectionOver() {
		return selectionOver;
	}

    public boolean isMouseOver() {
        return mouseOver;
    }

	public int getHitPoints() {
		return hitPoints;
	}

	public void setHitPoints(int hitPoints) {
		this.hitPoints = hitPoints;
	}

}